<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen 1.9.6"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>AngelScript: Inheriting from application registered class</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
  $(document).ready(function() { init_search(); });
/* @license-end */
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr id="projectrow">
  <td id="projectlogo"><img alt="Logo" src="aslogo_small.png"/></td>
  <td id="projectalign">
   <div id="projectname">AngelScript
   </div>
  </td>
    <td>        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <span id="MSearchSelect"                onmouseover="return searchBox.OnSearchSelectShow()"                onmouseout="return searchBox.OnSearchSelectHide()">&#160;</span>
          <input type="text" id="MSearchField" value="" placeholder="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.svg" alt=""/></a>
          </span>
        </div>
</td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.9.6 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
$(document).ready(function(){initNavTree('doc_adv_inheritappclass.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<div id="MSearchResults">
<div class="SRPage">
<div id="SRIndex">
<div id="SRResults"></div>
<div class="SRStatus" id="Loading">Loading...</div>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</div>
</div>
</div>

<div><div class="header">
  <div class="headertitle"><div class="title">Inheriting from application registered class </div></div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>A script class cannot directly inherit from an application registered class, as the script classes are not compiled into native machine code like the application classes are.</p>
<p>It is however possible to emulate the inheritance by using a proxy class to hide the underlying differences in an abstract layer. The proxy class has two parts, one is the C++ side that the application sees, and the other is the script side that the scripts can see and inherit from.</p>
<p>The following is an example implementation of such a proxy class.</p>
<div class="fragment"><div class="line"><span class="comment">// On the C++ side</span></div>
<div class="line"><span class="keyword">class </span>FooScripted</div>
<div class="line">{</div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line">  <span class="comment">// Public interface that we want the script to be able to override </span></div>
<div class="line">  <span class="keywordtype">void</span> CallMe()</div>
<div class="line">  {</div>
<div class="line">    <span class="comment">// If the script side is still alive, then call the scripted function</span></div>
<div class="line">    <span class="keywordflow">if</span>( !m_isDead-&gt;Get() )</div>
<div class="line">    {</div>
<div class="line">      <a class="code hl_class" href="classas_i_script_engine.html">asIScriptEngine</a> *engine = m_obj-&gt;GetEngine();</div>
<div class="line">      <a class="code hl_class" href="classas_i_script_context.html">asIScriptContext</a> *ctx = engine-&gt;<a class="code hl_function" href="classas_i_script_engine.html#a14fcb46b5193d8fd43680a5513d60200">RequestContext</a>();</div>
<div class="line"> </div>
<div class="line">      <span class="comment">// GetMethodByDecl returns the virtual function on the script class</span></div>
<div class="line">      <span class="comment">// thus when calling it, the VM will execute the derived method</span></div>
<div class="line">      ctx-&gt;<a class="code hl_function" href="classas_i_script_context.html#a43976f42dfc6c1af23e132d36265173a">Prepare</a>(m_obj-&gt;GetObjectType()-&gt;GetMethodByDecl(<span class="stringliteral">&quot;void CallMe()&quot;</span>));</div>
<div class="line">      ctx-&gt;<a class="code hl_function" href="classas_i_script_context.html#a10d3c152b25d07584999f4d9fe5ce8b1">SetObject</a>(m_obj);</div>
<div class="line">      ctx-&gt;<a class="code hl_function" href="classas_i_script_context.html#a8e52894432737acac2e1a422e496bf84">Execute</a>();</div>
<div class="line"> </div>
<div class="line">      engine-&gt;<a class="code hl_function" href="classas_i_script_engine.html#a22e42bf32902cbd6885731a6beeaca20">ReturnContext</a>(ctx);</div>
<div class="line">    }</div>
<div class="line">  }</div>
<div class="line"> </div>
<div class="line">  <span class="keywordtype">int</span> m_value;</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// A factory function that can be used by the script side to create</span></div>
<div class="line">  <span class="keyword">static</span> FooScripted *Factory()</div>
<div class="line">  {</div>
<div class="line">    <a class="code hl_class" href="classas_i_script_context.html">asIScriptContext</a> *ctx = <a class="code hl_function" href="group__api__principal__functions.html#gaf8b78824db10b0f757990805a4e18f70">asGetActiveContext</a>();</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Get the function that is calling the factory so we can be certain it is the FooScript script class</span></div>
<div class="line">    <a class="code hl_class" href="classas_i_script_function.html">asIScriptFunction</a> *func = ctx-&gt;<a class="code hl_function" href="classas_i_script_context.html#a31d663ebd833a39f63f30bd71ce6f6c5">GetFunction</a>(0);</div>
<div class="line">    <span class="keywordflow">if</span>( func-&gt;<a class="code hl_function" href="classas_i_script_function.html#a7adc88e37e7183ab621f4f8bcd7fcb5a">GetObjectType</a>() == 0 || std::string(func-&gt;<a class="code hl_function" href="classas_i_script_function.html#a7adc88e37e7183ab621f4f8bcd7fcb5a">GetObjectType</a>()-&gt;<a class="code hl_function" href="classas_i_type_info.html#abc55a188d925cdb256d20a23b9568777">GetName</a>()) != <span class="stringliteral">&quot;FooScripted&quot;</span> )</div>
<div class="line">    {</div>
<div class="line">      ctx-&gt;<a class="code hl_function" href="classas_i_script_context.html#a6f0f071215e0f7effc0b765043f01275">SetException</a>(<span class="stringliteral">&quot;Invalid attempt to manually instantiate FooScript_t&quot;</span>);</div>
<div class="line">      <span class="keywordflow">return</span> 0;</div>
<div class="line">    }</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Get the this pointer from the calling function so the FooScript C++</span></div>
<div class="line">    <span class="comment">// class can be linked with the FooScript script class</span></div>
<div class="line">    <a class="code hl_class" href="classas_i_script_object.html">asIScriptObject</a> *obj = <span class="keyword">reinterpret_cast&lt;</span><a class="code hl_class" href="classas_i_script_object.html">asIScriptObject</a>*<span class="keyword">&gt;</span>(ctx-&gt;<a class="code hl_function" href="classas_i_script_context.html#a2087d09329df514579b4b5a418c2e2f7">GetThisPointer</a>(0));</div>
<div class="line"> </div>
<div class="line">    <span class="keywordflow">return</span> <span class="keyword">new</span> FooScripted(obj);</div>
<div class="line">  }</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Reference counting</span></div>
<div class="line">  <span class="keywordtype">void</span> AddRef()</div>
<div class="line">  {</div>
<div class="line">    m_refCount++;</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Increment also the reference counter to the script side so</span></div>
<div class="line">    <span class="comment">// it isn&#39;t accidentally destroyed before the C++ side</span></div>
<div class="line">    <span class="keywordflow">if</span>( !m_isDead-&gt;Get() )</div>
<div class="line">      m_obj-&gt;AddRef();</div>
<div class="line">  }</div>
<div class="line">  <span class="keywordtype">void</span> Release()</div>
<div class="line">  { </div>
<div class="line">    <span class="comment">// Release the script instance too</span></div>
<div class="line">    <span class="keywordflow">if</span>( !m_isDead-&gt;Get() )</div>
<div class="line">      m_obj-&gt;Release();</div>
<div class="line"> </div>
<div class="line">    <span class="keywordflow">if</span>( --m_refCount == 0 ) <span class="keyword">delete</span> <span class="keyword">this</span>;</div>
<div class="line">  }</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Assignment operator</span></div>
<div class="line">  FooScripted &amp;operator=(<span class="keyword">const</span> FooScripted &amp;o)</div>
<div class="line">  {</div>
<div class="line">    <span class="comment">// Copy only the content, not the script proxy class</span></div>
<div class="line">    m_value = o.m_value;</div>
<div class="line">    <span class="keywordflow">return</span> *<span class="keyword">this</span>;</div>
<div class="line">  }</div>
<div class="line"> </div>
<div class="line"><span class="keyword">protected</span>:</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// The constructor and destructor are indirectly called</span></div>
<div class="line">  FooScripted(<a class="code hl_class" href="classas_i_script_object.html">asIScriptObject</a> *obj) : m_obj(0), m_isDead(0), m_value(0), m_refCount(1)</div>
<div class="line">  {</div>
<div class="line">    <span class="comment">// Get the weak ref flag for the script object to</span></div>
<div class="line">    <span class="comment">// avoid holding a strong reference to the script class</span></div>
<div class="line">    m_isDead = obj-&gt;<a class="code hl_function" href="classas_i_script_object.html#aee02bc4ac8d27683062de7e8f7e61084">GetWeakRefFlag</a>();</div>
<div class="line">    m_isDead-&gt;<a class="code hl_function" href="classas_i_lockable_shared_bool.html#a1183742552ce6b952cc3742bd456d787">AddRef</a>();</div>
<div class="line"> </div>
<div class="line">    m_obj = obj;</div>
<div class="line">  }</div>
<div class="line"> </div>
<div class="line">  ~FooScripted()</div>
<div class="line">  {</div>
<div class="line">    <span class="comment">// Release the weak ref flag</span></div>
<div class="line">    m_isDead-&gt;<a class="code hl_function" href="classas_i_script_object.html#a4bed3c3ac9f16294985835747aa122d3">Release</a>();</div>
<div class="line">  }</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Reference count</span></div>
<div class="line">  <span class="keywordtype">int</span> m_refCount;</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// The C++ side holds a weak link to the script side to</span></div>
<div class="line">  <span class="comment">// avoid a circular reference between the C++ side and</span></div>
<div class="line">  <span class="comment">// script side</span></div>
<div class="line">  <a class="code hl_class" href="classas_i_lockable_shared_bool.html">asILockableSharedBool</a> *m_isDead;</div>
<div class="line">  <a class="code hl_class" href="classas_i_script_object.html">asIScriptObject</a> *m_obj;</div>
<div class="line">};</div>
<div class="ttc" id="aclassas_i_lockable_shared_bool_html"><div class="ttname"><a href="classas_i_lockable_shared_bool.html">asILockableSharedBool</a></div><div class="ttdoc">A lockable shared boolean.</div><div class="ttdef"><b>Definition:</b> angelscript.h:4257</div></div>
<div class="ttc" id="aclassas_i_lockable_shared_bool_html_a1183742552ce6b952cc3742bd456d787"><div class="ttname"><a href="classas_i_lockable_shared_bool.html#a1183742552ce6b952cc3742bd456d787">asILockableSharedBool::AddRef</a></div><div class="ttdeci">virtual int AddRef() const =0</div><div class="ttdoc">Adds a reference to the shared boolean.</div></div>
<div class="ttc" id="aclassas_i_script_context_html"><div class="ttname"><a href="classas_i_script_context.html">asIScriptContext</a></div><div class="ttdoc">The interface to the virtual machine.</div><div class="ttdef"><b>Definition:</b> angelscript.h:2735</div></div>
<div class="ttc" id="aclassas_i_script_context_html_a10d3c152b25d07584999f4d9fe5ce8b1"><div class="ttname"><a href="classas_i_script_context.html#a10d3c152b25d07584999f4d9fe5ce8b1">asIScriptContext::SetObject</a></div><div class="ttdeci">virtual int SetObject(void *obj)=0</div><div class="ttdoc">Sets the object for a class method call.</div></div>
<div class="ttc" id="aclassas_i_script_context_html_a2087d09329df514579b4b5a418c2e2f7"><div class="ttname"><a href="classas_i_script_context.html#a2087d09329df514579b4b5a418c2e2f7">asIScriptContext::GetThisPointer</a></div><div class="ttdeci">virtual void * GetThisPointer(asUINT stackLevel=0)=0</div><div class="ttdoc">Returns a pointer to the object, if a class method is being executed.</div></div>
<div class="ttc" id="aclassas_i_script_context_html_a31d663ebd833a39f63f30bd71ce6f6c5"><div class="ttname"><a href="classas_i_script_context.html#a31d663ebd833a39f63f30bd71ce6f6c5">asIScriptContext::GetFunction</a></div><div class="ttdeci">virtual asIScriptFunction * GetFunction(asUINT stackLevel=0)=0</div><div class="ttdoc">Returns the function at the specified callstack level.</div></div>
<div class="ttc" id="aclassas_i_script_context_html_a43976f42dfc6c1af23e132d36265173a"><div class="ttname"><a href="classas_i_script_context.html#a43976f42dfc6c1af23e132d36265173a">asIScriptContext::Prepare</a></div><div class="ttdeci">virtual int Prepare(asIScriptFunction *func)=0</div><div class="ttdoc">Prepares the context for execution of the function.</div></div>
<div class="ttc" id="aclassas_i_script_context_html_a6f0f071215e0f7effc0b765043f01275"><div class="ttname"><a href="classas_i_script_context.html#a6f0f071215e0f7effc0b765043f01275">asIScriptContext::SetException</a></div><div class="ttdeci">virtual int SetException(const char *info, bool allowCatch=true)=0</div><div class="ttdoc">Sets an exception, which aborts the execution.</div></div>
<div class="ttc" id="aclassas_i_script_context_html_a8e52894432737acac2e1a422e496bf84"><div class="ttname"><a href="classas_i_script_context.html#a8e52894432737acac2e1a422e496bf84">asIScriptContext::Execute</a></div><div class="ttdeci">virtual int Execute()=0</div><div class="ttdoc">Executes the prepared function.</div></div>
<div class="ttc" id="aclassas_i_script_engine_html"><div class="ttname"><a href="classas_i_script_engine.html">asIScriptEngine</a></div><div class="ttdoc">The engine interface.</div><div class="ttdef"><b>Definition:</b> angelscript.h:1102</div></div>
<div class="ttc" id="aclassas_i_script_engine_html_a14fcb46b5193d8fd43680a5513d60200"><div class="ttname"><a href="classas_i_script_engine.html#a14fcb46b5193d8fd43680a5513d60200">asIScriptEngine::RequestContext</a></div><div class="ttdeci">virtual asIScriptContext * RequestContext()=0</div><div class="ttdoc">Request a context.</div></div>
<div class="ttc" id="aclassas_i_script_engine_html_a22e42bf32902cbd6885731a6beeaca20"><div class="ttname"><a href="classas_i_script_engine.html#a22e42bf32902cbd6885731a6beeaca20">asIScriptEngine::ReturnContext</a></div><div class="ttdeci">virtual void ReturnContext(asIScriptContext *ctx)=0</div><div class="ttdoc">Return a context when it won't be used anymore.</div></div>
<div class="ttc" id="aclassas_i_script_function_html"><div class="ttname"><a href="classas_i_script_function.html">asIScriptFunction</a></div><div class="ttdoc">The interface for a script function description.</div><div class="ttdef"><b>Definition:</b> angelscript.h:4000</div></div>
<div class="ttc" id="aclassas_i_script_function_html_a7adc88e37e7183ab621f4f8bcd7fcb5a"><div class="ttname"><a href="classas_i_script_function.html#a7adc88e37e7183ab621f4f8bcd7fcb5a">asIScriptFunction::GetObjectType</a></div><div class="ttdeci">virtual asITypeInfo * GetObjectType() const =0</div><div class="ttdoc">Returns the object type for class or interface method.</div></div>
<div class="ttc" id="aclassas_i_script_object_html"><div class="ttname"><a href="classas_i_script_object.html">asIScriptObject</a></div><div class="ttdoc">The interface for an instance of a script object.</div><div class="ttdef"><b>Definition:</b> angelscript.h:3590</div></div>
<div class="ttc" id="aclassas_i_script_object_html_a4bed3c3ac9f16294985835747aa122d3"><div class="ttname"><a href="classas_i_script_object.html#a4bed3c3ac9f16294985835747aa122d3">asIScriptObject::Release</a></div><div class="ttdeci">virtual int Release() const =0</div><div class="ttdoc">Decrease reference counter.</div></div>
<div class="ttc" id="aclassas_i_script_object_html_aee02bc4ac8d27683062de7e8f7e61084"><div class="ttname"><a href="classas_i_script_object.html#aee02bc4ac8d27683062de7e8f7e61084">asIScriptObject::GetWeakRefFlag</a></div><div class="ttdeci">virtual asILockableSharedBool * GetWeakRefFlag() const =0</div><div class="ttdoc">Returns the weak ref flag for the object.</div></div>
<div class="ttc" id="aclassas_i_type_info_html_abc55a188d925cdb256d20a23b9568777"><div class="ttname"><a href="classas_i_type_info.html#abc55a188d925cdb256d20a23b9568777">asITypeInfo::GetName</a></div><div class="ttdeci">virtual const char * GetName() const =0</div><div class="ttdoc">Returns a temporary pointer to the name of the datatype.</div></div>
<div class="ttc" id="agroup__api__principal__functions_html_gaf8b78824db10b0f757990805a4e18f70"><div class="ttname"><a href="group__api__principal__functions.html#gaf8b78824db10b0f757990805a4e18f70">asGetActiveContext</a></div><div class="ttdeci">AS_API asIScriptContext * asGetActiveContext()</div><div class="ttdoc">Returns the currently active context.</div></div>
</div><!-- fragment --><p>This type is registered with the engine as the following:</p>
<div class="fragment"><div class="line"><span class="keywordtype">void</span> RegisterFooScripted(<a class="code hl_class" href="classas_i_script_engine.html">asIScriptEngine</a> *engine)</div>
<div class="line">{</div>
<div class="line">  engine-&gt;<a class="code hl_function" href="classas_i_script_engine.html#a29c6c087c8c5b5cdb6271cfd161cc5a6">RegisterObjectType</a>(<span class="stringliteral">&quot;FooScripted_t&quot;</span>, 0, <a class="code hl_enumvalue" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aa9450e038342b36c745858d2e5ae4b861">asOBJ_REF</a>);</div>
<div class="line">  engine-&gt;<a class="code hl_function" href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;FooScripted_t&quot;</span>, <a class="code hl_enumvalue" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a0b3db16eea35213b6f41f8d19dc1bd4c">asBEHAVE_FACTORY</a>, <span class="stringliteral">&quot;FooScripted_t @f()&quot;</span>, <a class="code hl_define" href="angelscript_8h.html#a78f8f2c7f1c88b12e74a5ac47b4184ae">asFUNCTION</a>(FooScripted::Factory), <a class="code hl_enumvalue" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4">asCALL_CDECL</a>);</div>
<div class="line">  engine-&gt;<a class="code hl_function" href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;FooScripted_t&quot;</span>, <a class="code hl_enumvalue" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a1dfa5b72ad69a7bf70636d4fcb1b1d84">asBEHAVE_ADDREF</a>, <span class="stringliteral">&quot;void f()&quot;</span>, <a class="code hl_define" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a>(FooScripted, AddRef), <a class="code hl_enumvalue" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>);</div>
<div class="line">  engine-&gt;<a class="code hl_function" href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;FooScripted_t&quot;</span>, <a class="code hl_enumvalue" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a7134ce13c81967191af401a1e5170a0c">asBEHAVE_RELEASE</a>, <span class="stringliteral">&quot;void f()&quot;</span>, <a class="code hl_define" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a>(FooScripted, Release), <a class="code hl_enumvalue" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>);</div>
<div class="line">  engine-&gt;<a class="code hl_function" href="classas_i_script_engine.html#ad74043be9cc30f105c62f482ca720574">RegisterObjectMethod</a>(<span class="stringliteral">&quot;FooScripted_t&quot;</span>, <span class="stringliteral">&quot;FooScripted_t &amp;opAssign(const FooScripted_t &amp;in)&quot;</span>, <a class="code hl_define" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a>(FooScripted, <span class="keyword">operator</span>=), <a class="code hl_enumvalue" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>);</div>
<div class="line">  engine-&gt;<a class="code hl_function" href="classas_i_script_engine.html#ad74043be9cc30f105c62f482ca720574">RegisterObjectMethod</a>(<span class="stringliteral">&quot;FooScripted_t&quot;</span>, <span class="stringliteral">&quot;void CallMe()&quot;</span>, <a class="code hl_define" href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a>(FooScripted, CallMe), <a class="code hl_enumvalue" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a>);</div>
<div class="line">  engine-&gt;<a class="code hl_function" href="classas_i_script_engine.html#a0aa35bf824180fe6aed685b40f0e8c34">RegisterObjectProperty</a>(<span class="stringliteral">&quot;FooScripted_t&quot;</span>, <span class="stringliteral">&quot;int m_value&quot;</span>, <a class="code hl_define" href="angelscript_8h.html#a717eccea17214bc1eb64bb9789c4915a">asOFFSET</a>(FooScripted, m_value));</div>
<div class="line">}</div>
<div class="ttc" id="aangelscript_8h_html_a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4"><div class="ttname"><a href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4">asCALL_CDECL</a></div><div class="ttdeci">@ asCALL_CDECL</div><div class="ttdoc">A cdecl function.</div><div class="ttdef"><b>Definition:</b> angelscript.h:230</div></div>
<div class="ttc" id="aangelscript_8h_html_a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96"><div class="ttname"><a href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4aea516c8742acc1edff6a43dc1bb09e96">asCALL_THISCALL</a></div><div class="ttdeci">@ asCALL_THISCALL</div><div class="ttdoc">A thiscall class method.</div><div class="ttdef"><b>Definition:</b> angelscript.h:236</div></div>
<div class="ttc" id="aangelscript_8h_html_a717eccea17214bc1eb64bb9789c4915a"><div class="ttname"><a href="angelscript_8h.html#a717eccea17214bc1eb64bb9789c4915a">asOFFSET</a></div><div class="ttdeci">#define asOFFSET(s, m)</div><div class="ttdoc">Returns the offset of an attribute in a struct.</div><div class="ttdef"><b>Definition:</b> angelscript.h:682</div></div>
<div class="ttc" id="aangelscript_8h_html_a7345e6b3afabec24efd0ff77886d49a6"><div class="ttname"><a href="angelscript_8h.html#a7345e6b3afabec24efd0ff77886d49a6">asMETHOD</a></div><div class="ttdeci">#define asMETHOD(c, m)</div><div class="ttdoc">Returns an asSFuncPtr representing the class method specified by class and method name.</div><div class="ttdef"><b>Definition:</b> angelscript.h:750</div></div>
<div class="ttc" id="aangelscript_8h_html_a78f8f2c7f1c88b12e74a5ac47b4184ae"><div class="ttname"><a href="angelscript_8h.html#a78f8f2c7f1c88b12e74a5ac47b4184ae">asFUNCTION</a></div><div class="ttdeci">#define asFUNCTION(f)</div><div class="ttdoc">Returns an asSFuncPtr representing the function specified by the name.</div><div class="ttdef"><b>Definition:</b> angelscript.h:685</div></div>
<div class="ttc" id="aangelscript_8h_html_a7e38df5b10ec8cbf2a688f1d114097c5a0b3db16eea35213b6f41f8d19dc1bd4c"><div class="ttname"><a href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a0b3db16eea35213b6f41f8d19dc1bd4c">asBEHAVE_FACTORY</a></div><div class="ttdeci">@ asBEHAVE_FACTORY</div><div class="ttdoc">Factory.</div><div class="ttdef"><b>Definition:</b> angelscript.h:366</div></div>
<div class="ttc" id="aangelscript_8h_html_a7e38df5b10ec8cbf2a688f1d114097c5a1dfa5b72ad69a7bf70636d4fcb1b1d84"><div class="ttname"><a href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a1dfa5b72ad69a7bf70636d4fcb1b1d84">asBEHAVE_ADDREF</a></div><div class="ttdeci">@ asBEHAVE_ADDREF</div><div class="ttdoc">AddRef.</div><div class="ttdef"><b>Definition:</b> angelscript.h:370</div></div>
<div class="ttc" id="aangelscript_8h_html_a7e38df5b10ec8cbf2a688f1d114097c5a7134ce13c81967191af401a1e5170a0c"><div class="ttname"><a href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a7134ce13c81967191af401a1e5170a0c">asBEHAVE_RELEASE</a></div><div class="ttdeci">@ asBEHAVE_RELEASE</div><div class="ttdoc">Release.</div><div class="ttdef"><b>Definition:</b> angelscript.h:372</div></div>
<div class="ttc" id="aangelscript_8h_html_a855d86fa9ee15b9f75e553ee376b5c7aa9450e038342b36c745858d2e5ae4b861"><div class="ttname"><a href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aa9450e038342b36c745858d2e5ae4b861">asOBJ_REF</a></div><div class="ttdeci">@ asOBJ_REF</div><div class="ttdoc">A reference type.</div><div class="ttdef"><b>Definition:</b> angelscript.h:254</div></div>
<div class="ttc" id="aclassas_i_script_engine_html_a0aa35bf824180fe6aed685b40f0e8c34"><div class="ttname"><a href="classas_i_script_engine.html#a0aa35bf824180fe6aed685b40f0e8c34">asIScriptEngine::RegisterObjectProperty</a></div><div class="ttdeci">virtual int RegisterObjectProperty(const char *obj, const char *declaration, int byteOffset, int compositeOffset=0, bool isCompositeIndirect=false)=0</div><div class="ttdoc">Registers a property for the object type.</div></div>
<div class="ttc" id="aclassas_i_script_engine_html_a29c6c087c8c5b5cdb6271cfd161cc5a6"><div class="ttname"><a href="classas_i_script_engine.html#a29c6c087c8c5b5cdb6271cfd161cc5a6">asIScriptEngine::RegisterObjectType</a></div><div class="ttdeci">virtual int RegisterObjectType(const char *obj, int byteSize, asDWORD flags)=0</div><div class="ttdoc">Registers a new object type.</div></div>
<div class="ttc" id="aclassas_i_script_engine_html_a9f122dd87394f3a83ac766ea19f37317"><div class="ttname"><a href="classas_i_script_engine.html#a9f122dd87394f3a83ac766ea19f37317">asIScriptEngine::RegisterObjectBehaviour</a></div><div class="ttdeci">virtual int RegisterObjectBehaviour(const char *obj, asEBehaviours behaviour, const char *declaration, const asSFuncPtr &amp;funcPointer, asDWORD callConv, void *auxiliary=0, int compositeOffset=0, bool isCompositeIndirect=false)=0</div><div class="ttdoc">Registers a behaviour for the object type.</div></div>
<div class="ttc" id="aclassas_i_script_engine_html_ad74043be9cc30f105c62f482ca720574"><div class="ttname"><a href="classas_i_script_engine.html#ad74043be9cc30f105c62f482ca720574">asIScriptEngine::RegisterObjectMethod</a></div><div class="ttdeci">virtual int RegisterObjectMethod(const char *obj, const char *declaration, const asSFuncPtr &amp;funcPointer, asDWORD callConv, void *auxiliary=0, int compositeOffset=0, bool isCompositeIndirect=false)=0</div><div class="ttdoc">Registers a method for the object type.</div></div>
</div><!-- fragment --><p>The script side is declared as <a class="el" href="doc_script_shared.html">shared</a> so it can be used in all script modules. It is also declared as <a class="el" href="doc_script_class_inheritance.html#doc_script_class_inheritance_2">abstract</a> so it cannot be instantiated by itself, only as a parent class of another script class.</p>
<p>This script section should preferably be included automatically by the application in all the modules that should be able to derive from the FooScripted class.</p>
<pre>
  // On the script side
  shared abstract class FooScripted
  {
    // Allow scripts to create instances
    FooScripted()
    {
      // Create the C++ side of the proxy
      @m_obj = FooScripted_t();  
    }

    // The copy constructor performs a deep copy
    FooScripted(const FooScripted &amp;o)
    {
      // Create a new C++ instance and copy content
      @m_obj = FooScripted_t();
      m_obj = o.m_obj;
    }

    // Do a deep a copy of the C++ object
    FooScripted &amp;opAssign(const FooScripted &amp;o)
    {
      // copy content of C++ instance
      m_obj = o.m_obj;
      return this;
    }

    // The script side forwards the call to the C++ side
    void CallMe() { m_obj.CallMe(); }

    // The C++ side property is exposed to the script through accessors
    int m_value 
    {
      get { return m_obj.m_value; }
      set { m_obj.m_value = value; }
    }

    // The script class can be implicitly cast to the C++ type through the opImplCast method
    FooScripted_t @opImplCast() { return m_obj; }

    // Hold a reference to the C++ side of the proxy
    private FooScripted_t @m_obj;
  }
</pre><p>Now the scripts classes can derive from the FooScripted class <br  />
 and access the properties and methods of the parent class normally.</p>
<pre>
  // Implement a script class that derives from the application class
  class FooDerived : FooScripted
  {
    void CallMe()
    {
       m_value += 1;
    }
  }

  void main()
  {
    // When newly created the m_value is 0
    FooDerived d;
    assert( d.m_value == 0 );

    // When calling the method the m_value is incremented with 1
    d.CallMe();
    assert( d.m_value == 1 );
  }
</pre><p>It is of course also possible to create an instance of the scripted class from the application and access it through the FooScripted C++ proxy, thus making it transparent from the rest of the application that the implementation is actually in the script.</p>
<div class="fragment"><div class="line">FooScripted *CreateFooDerived(<a class="code hl_class" href="classas_i_script_engine.html">asIScriptEngine</a> *engine)</div>
<div class="line">{</div>
<div class="line">  <span class="comment">// Create an instance of the FooDerived script class that inherits from the FooScripted C++ class</span></div>
<div class="line">  <a class="code hl_class" href="classas_i_script_object.html">asIScriptObject</a> *obj = <span class="keyword">reinterpret_cast&lt;</span><a class="code hl_class" href="classas_i_script_object.html">asIScriptObject</a>*<span class="keyword">&gt;</span>(engine-&gt;<a class="code hl_function" href="classas_i_script_engine.html#a1a2b993e219d72c39181927c708d2aea">CreateScriptObject</a>(mod-&gt;GetTypeInfoByName(<span class="stringliteral">&quot;FooDerived&quot;</span>)));</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Get the pointer to the C++ side of the FooScripted class</span></div>
<div class="line">  FooScripted *obj2 = *<span class="keyword">reinterpret_cast&lt;</span>FooScripted**<span class="keyword">&gt;</span>(obj-&gt;<a class="code hl_function" href="classas_i_script_object.html#a8e6a40af06771e3da8ac1ee9bbfdddbb">GetAddressOfProperty</a>(0));</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Increase the reference count to the C++ object, as this is what will </span></div>
<div class="line">  <span class="comment">// be used to control the life time of the object from the application side </span></div>
<div class="line">  obj2-&gt;<a class="code hl_function" href="classas_i_script_object.html#a3e08890e31163e4d33c0f27dc9072662">AddRef</a>();</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Release the reference to the script side</span></div>
<div class="line">  obj-&gt;<a class="code hl_function" href="classas_i_script_object.html#a4bed3c3ac9f16294985835747aa122d3">Release</a>();</div>
<div class="line"> </div>
<div class="line">  <span class="keywordflow">return</span> obj2;</div>
<div class="line">}</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">void</span> Foo(<a class="code hl_class" href="classas_i_script_engine.html">asIScriptEngine</a> *engine)</div>
<div class="line">{</div>
<div class="line">  FooScripted *obj = CreateFooDerived(engine);</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Once the object is created the application can access it normally through</span></div>
<div class="line">  <span class="comment">// the FooScripted pointer, without having to know that the implementation</span></div>
<div class="line">  <span class="comment">// is actually done in the script.</span></div>
<div class="line"> </div>
<div class="line">  <span class="comment">// When newly created the m_value is 0</span></div>
<div class="line">  assert( obj-&gt;m_value == 0 );</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// When calling the method the m_value is incremented with 1 by the script </span></div>
<div class="line">  obj-&gt;CallMe();</div>
<div class="line">  assert( obj-&gt;m_value == 1 );</div>
<div class="line"> </div>
<div class="line">  <span class="comment">// Release the object to destroy the instance (this will also destroy the script side)</span></div>
<div class="line">  obj-&gt;Release();</div>
<div class="line">}</div>
<div class="ttc" id="aclassas_i_script_engine_html_a1a2b993e219d72c39181927c708d2aea"><div class="ttname"><a href="classas_i_script_engine.html#a1a2b993e219d72c39181927c708d2aea">asIScriptEngine::CreateScriptObject</a></div><div class="ttdeci">virtual void * CreateScriptObject(const asITypeInfo *type)=0</div><div class="ttdoc">Creates an object defined by its type.</div></div>
<div class="ttc" id="aclassas_i_script_object_html_a3e08890e31163e4d33c0f27dc9072662"><div class="ttname"><a href="classas_i_script_object.html#a3e08890e31163e4d33c0f27dc9072662">asIScriptObject::AddRef</a></div><div class="ttdeci">virtual int AddRef() const =0</div><div class="ttdoc">Increase reference counter.</div></div>
<div class="ttc" id="aclassas_i_script_object_html_a8e6a40af06771e3da8ac1ee9bbfdddbb"><div class="ttname"><a href="classas_i_script_object.html#a8e6a40af06771e3da8ac1ee9bbfdddbb">asIScriptObject::GetAddressOfProperty</a></div><div class="ttdeci">virtual void * GetAddressOfProperty(asUINT prop)=0</div><div class="ttdoc">Returns a pointer to the property referenced by prop.</div></div>
</div><!-- fragment --> </div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
  <ul>
    <li class="footer">Generated on Sun May 21 2023 10:12:39 for AngelScript by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.6 </li>
  </ul>
</div>
</body>
</html>
